package com.cxx.home.service.impl;

import com.cxx.home.entity.Task;
import com.cxx.home.mapper.TaskMapper;
import com.cxx.framework.web.CustomException;
import com.cxx.home.schedule.QuartzDto;
import com.cxx.home.schedule.QuartzUtils;
import com.cxx.home.service.QuartzService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

@Service
@Slf4j
public class QuartzServiceImpl implements QuartzService {
    @Resource
    private Scheduler scheduler;

    @Resource
    private TaskMapper taskMapper;

    @Override
    public List<QuartzDto> queryQuartzTask() {
        GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
        List<QuartzDto> quartzDtoList = new ArrayList<>();

        try {
            Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
            for (JobKey jobKey : jobKeys) {
                List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
                for (Trigger trigger : triggers) {
                    QuartzDto quartzDto = new QuartzDto();
                    // 获取名称和组别
                    quartzDto.setName(jobKey.getName());
                    quartzDto.setGroup(jobKey.getGroup());

                    // 获取类型和内容
                    Task task = taskMapper.selectById(jobKey.getName());
                    quartzDto.setType(task.getType());
                    quartzDto.setContent(task.getContent());

                    // 获取状态
                    // NONE（触发器不存在）NORMAL（正常执行） PAUSED（暂停）
                    // COMPLETE（完成） ERROR（执行出错） BLOCKED（阻塞）
                    Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
                    quartzDto.setStatus(triggerState.name());

                    // 获取执行时间
                    if (trigger instanceof CronTrigger) {
                        CronTrigger cronTrigger = (CronTrigger) trigger;
                        String cronExpression = cronTrigger.getCronExpression();
                        quartzDto.setCronExpression(cronExpression);
                    }
                    if (trigger instanceof SimpleTrigger) {
                        SimpleTrigger simpleTrigger = (SimpleTrigger) trigger;
                        Date startTime = simpleTrigger.getStartTime();
                        quartzDto.setExecuteTime(startTime);
                    }
                    quartzDtoList.add(quartzDto);
                }
            }
        } catch (SchedulerException e) {
            throw new CustomException("获取任务列表失败: " + e.getMessage());
        }

        return quartzDtoList;
    }

    @Override
    public void createQuartzTask(Task task) {
        try {
            JobKey jobKey = new JobKey(task.getId().toString());
            scheduler.scheduleJob(QuartzUtils.getJobDetail(task, jobKey), QuartzUtils.getTrigger(task, jobKey));
        } catch (SchedulerException e) {
            throw new CustomException("创建任务: {} " + task.getId() + "失败: {}" + e.getMessage());
        }
    }

    @Override
    public void updateQuartzTask(Task task) {
        try {
            JobKey jobKey = new JobKey(task.getId().toString());

            // 此时并未执行，则更新
            if (scheduler.getJobDetail(jobKey) != null) {
                Trigger oldTrigger = scheduler.getTriggersOfJob(jobKey).get(0);
                scheduler.rescheduleJob(oldTrigger.getKey(), QuartzUtils.getTrigger(task, jobKey));
            } else {
                // 如果已经执行，则新建
                scheduler.scheduleJob(QuartzUtils.getJobDetail(task, jobKey), QuartzUtils.getTrigger(task, jobKey));
            }
        } catch (SchedulerException e) {
            throw new CustomException("更新任务: {} " + task.getId() + "失败: {}" + e.getMessage());
        }
    }

    @Override
    public void deleteQuartzTask(JobKey jobKey) {
        try {
            scheduler.deleteJob(jobKey);
        } catch (SchedulerException e) {
            throw new CustomException("删除任务: {} " + jobKey.getName() + "失败: {}" + e.getMessage());
        }
    }
}
